﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using blackhouse.BlackApart.Business.Apartments;
using blackhouse.BlackApart.Business.Reservations;

namespace blackhouse.BlackApart.Business.Opinions {
    public class ImpOpinion : IOpinion {

        #region Fields

        private IApartmentGroup associatedGroup;

        #endregion

        #region Properties

        public int Id { get; set; }
        public string InPlusOpinion { get; set; }
        public string InMinusOpinion { get; set; }
        public string Answer { get; set; }
        public DateTime PublishedDate { get; set; }
        public AuthorOpinion Publisher { get; set; }
        public Dictionary<int, float> OpinionDetails { get; private set; }
        public int ApartmentGroupId { get; set; }
        public IOpinion[] SimilarOpinions { get; set; }
        public bool IsPublic { get; set; }

        #endregion

        #region Constructors

        public ImpOpinion() {
            this.OpinionDetails = new Dictionary<int, float>();
        }

        #endregion

        #region Methods

        public bool Save(int userId) {
            return Publisher != null && PublishedDate <= DateTime.Now;
        }

        public void AddOpinionDetailValue(int categoryId, float val) {
            if (this.OpinionDetails.ContainsKey(categoryId))
                this.OpinionDetails[categoryId] = val;
            else
                this.OpinionDetails.Add(categoryId, val);
        }

        public float GetAverageRating() {
            return Convert.ToSingle(Math.Round(this.OpinionDetails.Average(o => o.Value), 1));
        }

        public float GetOpinionDetailValue(int categoryId) {
            if (this.OpinionDetails.ContainsKey(categoryId))
                return Convert.ToSingle(Math.Round(this.OpinionDetails[categoryId], 1));
            else
                return 10f;
        }

        public IOpinion[] GetOpinions() {
            return new IOpinion[] { this };
        }

        public IOpinion[] GetOpinions(bool includeNonPublic) {
            return new IOpinion[] { this };
        }

        public void Publish(int userId) {
        }

        public int FindReservationToAddOpinion(int apartmentTypeId) {
            return 0;
        }

        public IApartmentGroup GetAssociatedApartmentGroup() {
            if (this.associatedGroup == null || this.associatedGroup.Id != this.ApartmentGroupId) {
                this.associatedGroup = Factory.Instance().GetApartmentGroup(this.ApartmentGroupId);
            }
            return this.associatedGroup;
        }

        public int GetAssociatedApartmentGroupId() {
            return this.ApartmentGroupId;
        }

        public IOpinion[] GetSimilarOpinions(int opinionId, TimeSpan timeWatch) {
            return this.SimilarOpinions;
        }

        public void Visit(IOpinionVisitor visitor) {
            visitor.Apply(this);
        }

        public bool Moderate(int userId) {
            return this.Save(userId);
        }

        public List<IWebReservation> FindInterviewerReservation() {
            InterviewerReservations resBase = Factory.Instance().CreateWebReservation() as InterviewerReservations;
            if (resBase != null)
                return resBase.FindReservationForInterviewer();
            else
                return new List<IWebReservation>(0);
        }

        #endregion



    }
}
